package com.viewpagerindicator.sample;

import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.text.method.ScrollingMovementMethod;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.viewpagerindicator.sample.util.ACache;
import com.viewpagerindicator.sample.util.Common;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.UUID;

/**
 * Created by zhao on 2015/11/11.
 */
public class SspPrintActivity extends AppCompatActivity {
    private final static String TAG = SspPrintActivity.class.getSimpleName();
    public static String SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB";
    public static final String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS";
    public static final String CONTENT_2_PRINT = "CONTENT_2_PRINT";
    private boolean mConnected = false;
    String mDeviceAddress=null;
    String content2Print=null;
    TextView messageShow;
    TextView progressTitle;
    BluetoothAdapter btAdapt=null;
    BluetoothSocket btSocket = null;
    private InputStream mmInStream;
    private OutputStream mmOutStream;
    Boolean bConnect = false;
    BluetoothDevice btDev=null;
    ACache mCache ;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.print_layout);
        mDeviceAddress = getIntent().getStringExtra(EXTRAS_DEVICE_ADDRESS);
        content2Print = getIntent().getStringExtra(CONTENT_2_PRINT);
        mCache=ACache.get(this);
        content2Print=mCache.getAsString(content2Print);
        if(mDeviceAddress==null){
            showDialog(getString(R.string.the_device_unvaliable),getString(R.string.click_ok_to_exit));
        }
        messageShow= (TextView) findViewById(R.id.show_message);
        progressTitle= (TextView) findViewById(R.id.progress_title);
        messageShow.setMovementMethod(ScrollingMovementMethod.getInstance());
        btAdapt = BluetoothAdapter.getDefaultAdapter();
        if (btAdapt == null) {
            showDialog(getString(R.string.dialog_title),getString(R.string.error_noblute));
            finish();
            return;
        }

        if (btAdapt.getState() != BluetoothAdapter.STATE_ON) {
            showDialog(getString(R.string.dialog_title), getString(R.string.bluetooth_failed));
            finish();
            return;
        }
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
        intentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
        intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
        intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
        intentFilter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
        intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        registerReceiver(connectDevices, intentFilter);
        btDev = btAdapt.getRemoteDevice(mDeviceAddress);
        if(btDev.getBondState()==BluetoothDevice.BOND_NONE){
            toLog("该设备尚未配对，开始配对");
            mHandler.sendEmptyMessageDelayed(Common.MESSAGE_TO_BONE, 1000);
        }else{
            toLog("该设备已配对，开始连接");
            mHandler.sendEmptyMessageDelayed(Common.MESSAGE_CONNECT, 1000);
        }
    }
    public final Handler mHandler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message message) {
            switch (message.what){
                case Common.MESSAGE_CONNECT:
                    toLog("开始连接蓝牙");
                    new Thread(new Runnable() {
                        public void run() {
                            InputStream tmpIn;
                            OutputStream tmpOut;
                            try {
                                UUID uuid = UUID.fromString(SPP_UUID);
//                                BluetoothDevice btDev = btAdapt.getRemoteDevice(mDeviceAddress);
                                btSocket = btDev.createInsecureRfcommSocketToServiceRecord(uuid);
                                //.createRfcommSocketToServiceRecord(uuid);
                                btSocket.connect();
                                tmpIn = btSocket.getInputStream();
                                tmpOut = btSocket.getOutputStream();
                            } catch (Exception e) {
                                bConnect = false;
                                Log.d(Common.TAG, "Error connected to: "+ mDeviceAddress);
                                mmInStream = null;
                                mmOutStream = null;
                                btSocket = null;
                                e.printStackTrace();
                                mHandler.sendEmptyMessage(Common.MESSAGE_CONNECT_LOST);
                                return;
                            }
                            mmInStream = tmpIn;
                            mmOutStream = tmpOut;
                            mHandler.sendEmptyMessage(Common.MESSAGE_CONNECT_SUCCEED);
                        }
                    }).start();
                    break;
                case Common.MESSAGE_CONNECT_SUCCEED:
                    toLog("连接正常，可以正常通信,发送Pc;指令\r\n等待接收数据指令");
                    bConnect = true;
                    new Thread(new Runnable() {
                        public void run() {
                            byte[] bufRecv = new byte[1024];
                            int nRecv = 0;
                            while (bConnect) {
                                try {
                                    nRecv = mmInStream.read(bufRecv);
                                    if (nRecv < 1) {
                                        Thread.sleep(100);
                                        continue;
                                    }

                                    byte[] nPacket = new byte[nRecv];
                                    System.arraycopy(bufRecv, 0, nPacket, 0, nRecv);
                                    mHandler.obtainMessage(Common.MESSAGE_RECV, nRecv, -1, nPacket).sendToTarget();
                                    Thread.sleep(100);
                                } catch (Exception e) {
                                    Log.e(Common.TAG, "Recv thread:" + e.getMessage());
                                    mHandler.sendEmptyMessage(Common.MESSAGE_EXCEPTION_RECV);
                                    break;
                                }
                            }
                            Log.e(Common.TAG, "Exit while");
                        }
                    }).start();
                    mHandler.sendEmptyMessage(Common.MESSAGE_SEND_PC);
                    break;
                case Common.MESSAGE_EXCEPTION_RECV:
                case Common.MESSAGE_TO_BONE:
                    // 配对
                    try {
                        BluetoothDevice btDev = btAdapt.getRemoteDevice(mDeviceAddress);
                        Method createBondMethod = BluetoothDevice.class.getMethod("createBond");
                        createBondMethod.invoke(btDev);
//                        mHandler.sendEmptyMessageDelayed(Common.MESSAGE_CONNECT, 1000);
                    } catch (Exception e) {
                        showDialog("提示","配对失败");
                    }
                    break;
                case Common.MESSAGE_CONNECT_LOST:
                    try {
                        if (mmInStream != null)
                            mmInStream.close();
                        if (mmOutStream != null)
                            mmOutStream.close();
                        if (btSocket != null)
                            btSocket.close();
                    } catch (IOException e) {
                        Log.e(Common.TAG, "Close Error");
                        e.printStackTrace();
                    } finally {
                        mmInStream = null;
                        mmOutStream = null;
                        btSocket = null;
                        bConnect = false;
                    }
                    showDialog("错误","连接异常，请退出本界面后重新连接1!");
                    break;
                case  Common.MESSAGE_SEND_PC:
                    try {
                        send("PC;");
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    break;
                case Common.MESSAGE_WRITE:

                    break;
                case Common.MESSAGE_READ:

                    break;
                case Common.MESSAGE_RECV:
                    byte[] bBuf = (byte[]) message.obj;
                    String data = new String(bBuf);
                    toLog("收到指令："+data);
                    if(data!=null&&(data.equals("C")||data.equals("c"))){
                        toLog("数据发送中,请勿退出...");
                        try {
                            send(content2Print);
                        } catch (Exception e) {
                            showDialog("错误","发送数据时发生异常!");
                            break;
                        }
                        toLog("发送完毕! 您可以：继续等待打印 或者 点击返回键退出.");
                        showDialogToExit();
                    }
                    break;
                case Common.MESSAGE_TOAST:
                    Toast.makeText(getApplicationContext(),
                            message.getData().getString(Common.TOAST),
                            Toast.LENGTH_SHORT).show();
                    break;
            }
            return false;
        }
    }) ;
    public static String bytesToString(byte[] b, int length) {
        StringBuffer result = new StringBuffer("");
        for (int i = 0; i < length; i++) {
            result.append((char) (b[i]));
        }
        return result.toString();
    }
    private BroadcastReceiver connectDevices = new BroadcastReceiver() {

        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            Log.d(TAG, "Receiver:" + action);
            if (action.equals(BluetoothDevice.ACTION_ACL_CONNECTED)) {

            } else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
                showDialog("错误","连接异常，请退出本界面后重新连接2!");
            }else if(action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)){
                if(btDev.getBondState()==BluetoothDevice.BOND_BONDED){
                    toLog("配对成功");
                    mHandler.sendEmptyMessageDelayed(Common.MESSAGE_CONNECT, 1000);
                }else{
                    toLog("配对失败，请到系统设置中配对");
                    showDialog("提示","配对失败，请到系统设置中进行配对");
                }
            }
        }
    };

    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    protected void onDestroy() {
        this.unregisterReceiver(connectDevices);
        try {
            if (mmInStream != null)
                mmInStream.close();
            if (mmOutStream != null)
                mmOutStream.close();
            if (btSocket != null)
                btSocket.close();
        } catch (IOException e) {
            Log.e(Common.TAG, "Close Error");
        } finally {
            mmInStream = null;
            mmOutStream = null;
            btSocket = null;
            bConnect = false;
        }
        super.onDestroy();
    }
    public void showDialog(String title,String msg){
        AlertDialog.Builder builder=new AlertDialog.Builder(this);
        builder.setTitle(title);
        builder.setMessage(msg);
        builder.setNegativeButton(R.string.btn_ok, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                dialogInterface.dismiss();
                finish();
            }
        });
        builder.show();
    }
    public void toLog(String msg){
        messageShow.append("\r\n" + msg);
        int offset=messageShow.getLineCount()*messageShow.getLineHeight();
        if(offset>messageShow.getHeight()){
            messageShow.scrollTo(0,offset-messageShow.getHeight());
        }
    }
    public void showDialogToExit(){
        AlertDialog.Builder builder=new AlertDialog.Builder(this);
        builder.setTitle(R.string.dialog_title);
        builder.setMessage(R.string.print_over);
        builder.setNegativeButton(R.string.print_over_return, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                dialogInterface.dismiss();
                finish();
            }
        });
        builder.setPositiveButton(R.string.print_over_continue, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {
                dialogInterface.dismiss();
                mHandler.sendEmptyMessage(Common.MESSAGE_SEND_PC);
            }
        });
        builder.show();
    }
    /* DEMO版较为简单，在编写您的应用时，请将此函数放到线程中执行，以免UI不响应 */
    public void send(String strValue) throws Exception {
        if (!bConnect)
            throw new Exception("未连接");
        if (mmOutStream == null)
            throw new Exception("连接错误");
        mmOutStream.write(strValue.getBytes());

    }
    public void back(View view){
        finish();
    }
}
